package com.hc.fdkforwarders.handler;

import com.hc.fdkforwarders.service.base.BaseService;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * @Description 释放ThreadLocal中的资源
 * @Author liuyuqing
 * @Date 2020/11/20 15:53
 **/
@Slf4j
@WebFilter(value = "/*", filterName = "threadLocalFilter")
public class ThreadLocalFinalizer implements Filter {

    @Resource
    BaseService baseService;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
            FilterChain filterChain) throws IOException, ServletException {
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            holders()
                    .stream()
                    .filter(a -> a instanceof ThreadLocalHolder)
                    .map(a -> (ThreadLocalHolder) a)
                    .forEach(h -> {
                        try {
                            h.onContextClosed();
                        } catch (Exception e) {
                            log.error("ThreadLocalFinalizeError", e);
                        }
                    });
        }
    }

    /**
     * 需要释放 ThreadLocal 资源的 Bean
     * <p>
     * 子类中覆盖 {@link ThreadLocalHolder#onContextClosed()} 方法时首先调用父类中的该方法
     */
    private List<Object> holders() {
        return Arrays.asList(
                baseService
        );
    }
}
